﻿#define TContinueWith

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Trock.Learning.TaskAbount
{
    class Program
    {
        #region Task ContinueWith
#if TContinueWith1

        static void Main(string[] args)
        {
            Task<string> t1 = Task.Factory.StartNew<string>(() =>
            {
                Console.WriteLine(string.Format("t1 start on {0}", DateTime.Now.ToString("HH:mm:ss.fff")));
                Thread.Sleep(2000);//撸管2min
                return string.Format("tired...... {0}", DateTime.Now.ToString("HH:mm:ss.fff"));
            }).ContinueWith<string>(task =>
             {
                 Console.WriteLine(string.Format("are you ok? {0}", DateTime.Now.ToString("HH:mm:ss.fff")));
                 Console.WriteLine(task.Result);
                 return "over";
             });

            Task.WaitAll(t1);
            Console.WriteLine(t1.Result);

            Console.WriteLine("i am a teacher");

            Console.ReadKey();
        }

#endif

#if TContinueWith

        static void Main(string[] args)
        {
            CancellationTokenSource cts = new CancellationTokenSource(5000);
            try
            {
                //开始采集检测图像
                Task<List<Bitmap>> images = Task.Factory.StartNew<List<Bitmap>>(() =>
                {
                    #region 采集图像
                    List<Bitmap> bmps = new List<Bitmap>();
                    //触发相机
                    for (int i = 0; i < 4; i++)
                    {
                        //触发
                        Console.WriteLine(string.Format("{0} ID[{1}]:softtrigger[{2}]", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId, i + 1));
                        //获取图像
                        Bitmap bmp = new Bitmap(800, 600, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                        bmps.Add(bmp);
                        Console.WriteLine(string.Format("{0} ID[{1}]:image[{2}]", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId, i + 1));
                        Thread.Sleep(50);//添加一个间隔，防止触发事件太短，相机触发不成功的情况

                        if (cts.Token.IsCancellationRequested)
                            break;
                    }
                    return bmps;
                    #endregion
                }, cts.Token);

                images.Wait(cts.Token);//等待检测图像采集完成
                //打开光源，采集清空图
                Task<Bitmap> light = Task.Factory.StartNew<Bitmap>(() =>
                {
                    if (cts.Token.IsCancellationRequested)//判断采集图像超时
                        return null;
                    #region 采集清空图
                    #region 操作完整性
                    //打开光源
                    Console.WriteLine(string.Format("{0} ID[{1}]:open light...", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    Thread.Sleep(500);//等待500ms或者更久后采集清空图像
                    if (cts.Token.IsCancellationRequested)
                        return null;
                    //触发
                    Console.WriteLine(string.Format("{0} ID[{1}]:clear dust softtrigger", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    //获取图像
                    Bitmap bmp = new Bitmap(800, 600, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
                    //关闭光源
                    Console.WriteLine(string.Format("{0} ID[{1}]:close light", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));

                    #endregion
                    if (cts.Token.IsCancellationRequested)
                        return null;
                    //标定
                    Console.WriteLine(string.Format("{0} ID[{1}]:标定清灰图像...", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    Thread.Sleep(300);
                    Console.WriteLine(string.Format("{0} ID[{1}]:清灰图像采集完成", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    if (cts.Token.IsCancellationRequested)
                        return null;
                    return bmp;
                    #endregion
                }, cts.Token);

                Task<int> check = Task.Factory.StartNew<int>(() =>
                {
                    #region 检测
                    Console.WriteLine(string.Format("{0} ID[{1}]:图像采集完成", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    //求平均值
                    Console.WriteLine(string.Format("{0} ID[{1}]:求平均值...", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    Thread.Sleep(100);
                    if (cts.Token.IsCancellationRequested)
                        return -1;
                    //标定图像
                    Console.WriteLine(string.Format("{0} ID[{1}]:标定图像...", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    Thread.Sleep(300);
                    if (cts.Token.IsCancellationRequested)
                        return -2;
                    //释放图像资源
                    images.Result.ForEach(x => x.Dispose());
                    images.Result.Clear();
                    Console.WriteLine(string.Format("{0} ID[{1}]:图像资源清除完毕", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    //调用算法检测
                    Console.WriteLine(string.Format("{0} ID[{1}]:开始检测...", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    Thread.Sleep(2000);
                    if (cts.Token.IsCancellationRequested)
                        return -3;
                    //返回检测结果                    
                    Console.WriteLine(string.Format("{0} ID[{1}]:检测完成", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    return 0;//返回检测结果 
                    #endregion
                });

                Task.WaitAll(new Task[] { light, check }, cts.Token); //清空图采集完成，检测完成
                Task.Factory.StartNew(() =>
                {
                    if (check.Result < 0)
                    {
                        Console.WriteLine(string.Format("{0} ID[{1}]:检测超时", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                        return;
                    }
                    Console.WriteLine(string.Format("{0} ID[{1}]:开始清灰...", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    if (light.Result != null)
                    {
                        light.Result.Dispose();
                        Console.WriteLine(string.Format("{0} ID[{1}]:释放清灰图", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                    }
                    Console.WriteLine(string.Format("{0} ID[{1}]:检测结果:{2}", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId, check.Result));
                    Console.WriteLine(string.Format("{0} ID[{1}]:清灰完成", DateTime.Now.ToString("HH:mm:ss.fff"), Task.CurrentId));
                });
            }
            catch (AggregateException ex)
            {
                foreach (var temp in ex.InnerExceptions)
                {
                    Console.WriteLine(temp.GetType().ToString());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
            Console.ReadKey();
        }

#endif
        #endregion
    }
}
